﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Problem19
{
    class Program
    {
        private static List<int> months = new List<int>(12)
        {
            31,
            28,
            31,
            30,
            31,
            30,
            31,
            31,
            30,
            31,
            30,
            31
        };

        enum WeekDays
        {
            Sunday,
            Monday,
            Tuesday,
            Wednesday,
            Thursday,
            Friday,
            Saturday
        };

        static void Main(string[] args)
        {
            int day = 1; int month = 0; int year = 1900;
            WeekDays weekDay = WeekDays.Monday;

            int endDay = 1; int endMonth = 0; int endYear = 2001;

            int sundays = 0;

            while (!(day == endDay && month == endMonth && year == endYear))
            {
                if (weekDay == WeekDays.Sunday && year >= 1901 && day == 1)
                {
                    sundays++;
                }

                IncreaseDay(day, month, year, out day, out month, out year);
                weekDay = GetNextWeekDay(weekDay);
            }

            Console.WriteLine(sundays);
            Console.ReadKey();
        }

        private static void IncreaseDay(int currentDay, int currentMonth, int currentYear, out int day, out int month, out int year)
        {
            year = currentYear; day = currentDay; month = currentMonth;

            if (currentDay == 31 && currentMonth == 11)
            {
                day = 1; month = 0; year = currentYear += 1;
                return;
            }

            if (currentDay == months[currentMonth] && currentMonth != 1)
            {
                day = 1; month = (currentMonth + 1) % 12; return;
            }

            if (currentDay != months[currentMonth] && currentMonth != 1)
            {
                day = currentDay + 1; return;
            }

            if (currentMonth == 1)
            {
                if (IsLeap(currentYear))
                {
                    if (months[currentMonth] == currentDay + 1)
                    {
                        month = currentMonth + 1;
                        day = 1;
                    }
                    else
                    {
                        day = currentDay + 1;
                    }
                }
                else
                {
                    if (months[currentMonth] == currentDay)
                    {
                        month = currentMonth + 1;
                        day = 1;
                    }
                    else
                    {
                        day = currentDay + 1;
                    }
                }
            }
        }

        private static bool IsLeap(int year)
        {
            if (year % 400 == 0)
            {
                return true;
            }
            
            if (year % 100 == 0)
            {
                return false;
            }

            if (year % 4 == 0)
            {
                return true;
            }
            
            return false;
        }

        private static WeekDays GetNextWeekDay(WeekDays weekDay)
        {
            switch (weekDay)
            {
                case WeekDays.Saturday:
                    return WeekDays.Sunday;
                case WeekDays.Sunday:
                    return WeekDays.Monday;
                case WeekDays.Monday:
                    return WeekDays.Tuesday;
                case WeekDays.Tuesday:
                    return WeekDays.Wednesday;
                case WeekDays.Wednesday:
                    return WeekDays.Thursday;
                case WeekDays.Thursday:
                    return WeekDays.Friday;
                case WeekDays.Friday:
                    return WeekDays.Saturday;
                default:
                    throw new ArgumentException("Unknown weekday value {0}", weekDay.ToString()); 
            };
        }
    }
}
